<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>09_生成器(Generator)-生成器函数的使用</title>
  <!-- 
  在 JavaScript 中，生成器函数是一种特殊类型的函数，它可以暂停执行并在需要时恢复。生成器函数的使用非常灵活，能够处理异步操作、迭代数据等。
  1. 生成器函数的定义

  生成器函数使用  `function*`  关键字定义。与普通函数不同，生成器函数可以使用  `yield`  关键字暂停执行并返回一个值。
  function* generatorFunction() {
      yield 1;
      yield 2;
      yield 3;
  }
  2. 创建生成器对象

  调用生成器函数会返回一个生成器对象，该对象可以通过调用  `next()`  方法逐步执行。
  const generator = generatorFunction();
  console.log(generator.next()); // 输出: { value: 1, done: false }
  console.log(generator.next()); // 输出: { value: 2, done: false }
  console.log(generator.next()); // 输出: { value: 3, done: false }
  console.log(generator.next()); // 输出: { value: undefined, done: true }
  3. 使用  `yield`  关键字

  `yield`  关键字用于暂停生成器函数的执行并返回一个值。每次调用  `next()`  方法时，生成器函数会从上次暂停的地方继续执行。

  4. 与  `for...of`  循环结合使用

  生成器对象是可迭代的，可以与  `for...of`  循环结合使用，方便地遍历生成器产生的值。
  for (const value of generatorFunction()) {
      console.log(value); // 输出: 1, 2, 3
  }
  5. 生成器的状态管理

  生成器函数可以保持内部状态。你可以在生成器中使用  `yield`  来管理状态，并根据需要返回不同的值。

  6. 异步操作

  生成器函数可以与 Promise 结合使用，实现异步操作的控制流。使用  `yield`  可以暂停执行，等待 Promise 解决后再继续执行。
  function* asyncGenerator() {
      const data1 = yield fetch('https://api.example.com/data1');
      console.log(data1);
      const data2 = yield fetch('https://api.example.com/data2');
      console.log(data2);
  }

  // 使用生成器处理异步操作的示例
  const gen = asyncGenerator();
  const promise1 = gen.next().value; // 获取第一个 Promise
  promise1.then(response => response.json()).then(data => {
      gen.next(data); // 继续执行生成器
  });
  7. 总结

  生成器函数提供了一种强大的方式来处理迭代和异步操作。它们的主要优点包括：
  - 可暂停和恢复：允许函数在执行过程中暂停，保持状态并在需要时恢复。
  - 简化异步编程：通过与 Promise 结合使用，可以使异步代码更加清晰。
  - 可迭代性：生成器对象是可迭代的，可以与  `for...of`  循环等结构结合使用。

  生成器函数在处理复杂的控制流和状态管理时非常有用，适合用于许多编程场景。
  -->
</head>
<body>

  <script>
    /**
     * 生成器函数: 
     *  1. function* fn(){} 生成器函数, 函数后面的*号表示这是一个生成器函数
     *  2. 代码的执行可以被yield中断, 可以通过next方法来恢复执行
     *  3. 生成器函数执行后返回一个生成器对象
     *  4. 当遇到yield时, 就会中断执行
    */

    // 1. 生成器函数
    function* fn() {
      console.log('start');
      yield
      console.log('end');
    }

    // 2. 执行生成器函数
    const generator = fn();
    console.log(generator); // Generator {<suspended>}

    // 3. 通过next方法来恢复执行
    generator.next(); // start
    generator.next(); // end


  </script>
  
</body>
</html>